package com.xk._01基础篇._00LeetCode._栈;

import java.util.HashMap;
import java.util.LinkedList;

/*
 * 20. 有效的括号
 * https://leetcode.cn/problems/valid-parentheses/
 *
 * 给定一个只包括 '('，')'，'{'，'}'，'['，']' 的字符串 s ，判断字符串是否有效。
 * 有效字符串需满足：
 *          1 左括号必须用相同类型的右括号闭合。
 *          2 左括号必须以正确的顺序闭合。
 *          3 每个右括号都有一个对应的相同类型的左括号。
 */
public class Test01 {
    private HashMap<Character, Character> map;

    public Test01(HashMap<Character, Character> map) {
        map = new HashMap<>();
        map.put('(', ')');
        map.put('{', '}');
        map.put('[', ']');
    }

    public boolean isValid(String s) {
        LinkedList<Character> stack = new LinkedList<>();

        int len = s.length();
        for (int i = 0; i < len; i++) {
            char c = s.charAt(i);
            if (map.containsKey(c)){ //左字符
                stack.push(c);
            } else {
                if (stack.isEmpty()) return false;
                char left = stack.pop();
                if (map.get(left) != c) return false;
            }
        }

        return stack.isEmpty();
    }



    /*
    1. 遇见左字符，将左字符入栈
    2. 遇见右字符 
        如果栈是空的，说明括号无效 
        如果栈不为空，将栈顶字符出栈，与右字符之匹配
            ✓ 如果左右字符不匹配，说明括号无效
            ✓ 如果左右字符匹配，继续扫描下一个字符
    3. 所有字符扫描完毕后
            ✓ 栈为空，说明括号有效
            ✓ 栈不为空，说明括号无效
     */

    public boolean isValid2(String s) {
        LinkedList<Character> stack = new LinkedList<>();
        int len = s.length();
        for (int i = 0; i < len; i++) {
            char c = s.charAt(i);
            if (c == '(' || c == '{' || c == '['){ //左字符
                stack.push(c);
            } else {
                if (stack.isEmpty()) return false;
                char left = stack.pop();
                if (left == '(' && c != ')') return false;
                if (left == '[' && c != ']') return false;
                if (left == '{' && c != '}') return false;
            }
        }

        return stack.isEmpty();
    }




    /*
    * [{()}]
    * */
    public boolean isValid1(String s) {
        while (s.contains("{}") || s.contains("()") || s.contains("[]")){
            s = s.replace("{}", "");
            s = s.replace("[]", "");
            s = s.replace("()", "");
        }

        return s.isEmpty();
    }
}
